﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Redis.Utils
{
    /// <summary>
    /// List操作
    /// </summary>
    public partial class RedisClient
    {
        #region List commands
        /// <summary>
        /// 从自定的范围内返回序列的元素
        /// </summary>
        /// <param name="key"></param>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        private byte[][] _ListRange(string key, int start, int end)
        {
            if (!CheckKey(key))
            {
                return null;
            }
            return redisSocket.SendDataCommandExpectMultiBulkReply(null, "LRANGE {0} {1} {2}\r\n", key, start, end);
        }

        /// <summary>
        /// 从自定的范围内返回序列的元素
        /// </summary>
        /// <param name="key"></param>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        public List<object> ListRange(string key, int start, int end)
        {
            byte[][] data = _ListRange(key, start, end);
            if (data == null || data.Length == 0)
            {
                return null;
            }
            List<object> returnData = new List<object>();
            foreach (byte[] item in data)
            {
                returnData.Add(Deserialize(item));
            }
            return returnData;
        }
        /// <summary>
        /// 返回列表所有数据
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public List<object> ListRange(string key)
        {
            return ListRange(key, 0, this.ListLength(key) - 1);
        }
        /// <summary>
        /// 从 List 尾部添加一个元素
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public void RightPush(string key, object value)
        {
            if (!CheckKeyAndValue(key, value))
            {
                return;
            }
            byte[] data = Serialize(value);
            //redisSocket.SendExpectSuccess("RPUSH {0} {1}\r\n{2}\r\n", key, data.Length, data);
            if (!redisSocket.SendDataCommand(data, "RPUSH {0} {1}\r\n", key, data.Length))
                throw new Exception("Unable to connect");
            redisSocket.ExpectSuccess();
        }

        /// <summary>
        /// 从 List 头部添加一个元素
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public void LeftPush(string key, object value)
        {
            if (!CheckKeyAndValue(key, value))
            {
                return;
            }
            byte[] data = Serialize(value);
            //redisSocket.SendExpectSuccess("LPUSH {0} {1}\r\n{2}\r\n", key, data.Length, data);
            if (!redisSocket.SendDataCommand(data, "LPUSH {0} {1}\r\n", key, data.Length))
                throw new Exception("Unable to connect");
            redisSocket.ExpectSuccess();
        }

        /// <summary>
        /// 返回一个 List 的长度
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public int ListLength(string key)
        {
            if (!CheckKey(key))
            {
                return 0;
            }
            return redisSocket.SendExpectInt("LLEN {0}\r\n", key);
        }

        /// <summary>
        /// 返回某个位置的序列值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        private byte[] _ListIndex(string key, int index)
        {
            if (!CheckKey(key))
            {
                return null;
            }
            redisSocket.SendCommand("LINDEX {0} {1}\r\n", key, index);
            return redisSocket.ReadData();
        }

        /// <summary>
        /// 返回某个位置的序列值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        public object ListIndex(string key, int index)
        {
            byte[] data = _ListIndex(key, index);
            if (data == null || data.Length == 0)
            {
                return null;
            }
            return Deserialize(data);
        }

        /// <summary>
        ///  弹出 List 的第一个元素
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        private byte[] _LeftPop(string key)
        {
            if (!CheckKey(key))
            {
                return null;
            }

            return redisSocket.SendExpectData(null, "LPOP {0}\r\n", key);


        }

        /// <summary>
        ///  弹出 List 的第一个元素
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public object LeftPop(string key)
        {
            byte[] data = _LeftPop(key);
            if (data == null || data.Length == 0)
            {
                return null;
            }
            return Deserialize(data);
        }

        /// <summary>
        ///  弹出 List 的最后一个元素
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        private byte[] _RightPop(string key)
        {
            if (!CheckKey(key))
            {
                return null;
            }
            return redisSocket.SendExpectData(null, "RPOP {0}\r\n", key);
        }

        /// <summary>
        ///  弹出 List 的最后一个元素
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public object RightPop(string key)
        {
            byte[] data = _RightPop(key);
            if (data == null || data.Length == 0)
            {
                return null;
            }
            return Deserialize(data);
        }
        #endregion
    }
}
